/*******************************************************************************
  System Initialization File

  File Name:
    system_init.c

  Summary:
    This file contains source code necessary to initialize the system.

  Description:
    This file contains source code necessary to initialize the system.  It
    implements the "SYS_Initialize" function, configuration bits, and allocates
    any necessary global system resources, such as the systemObjects structure
    that contains the object handles to all the MPLAB Harmony module objects in
    the system.
 *******************************************************************************/

// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc.  All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
 *******************************************************************************/
// DOM-IGNORE-END


// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include "system_config.h"
#include "system_definitions.h"
#include "app.h"
#include "app1.h"
#include "app2.h"
#include "app3.h"
#include "app4.h"
#include "app5.h"
#include "user_config.h"


// ****************************************************************************
// ****************************************************************************
// Section: Configuration Bits
// ****************************************************************************
// ****************************************************************************

/*** DEVCFG0 ***/

#pragma config DEBUG =      OFF
#pragma config ICESEL =     ICS_PGx2
#pragma config PWP =        0xff
#pragma config BWP =        OFF
#pragma config CP =         OFF

/*** DEVCFG1 ***/

#pragma config FNOSC =      PRIPLL
#pragma config FSOSCEN =    OFF
#pragma config IESO =       ON
#pragma config POSCMOD =    XT
#pragma config OSCIOFNC =   OFF
#pragma config FPBDIV =     DIV_1
#pragma config FCKSM =      CSDCMD
#pragma config WDTPS =      PS1048576
#pragma config FWDTEN =     OFF

/*** DEVCFG2 ***/

#pragma config FPLLIDIV =   DIV_1
#pragma config FPLLMUL =    MUL_20
#pragma config FPLLODIV =   DIV_2
#pragma config UPLLIDIV =   DIV_1
#pragma config UPLLEN =     OFF

/*** DEVCFG3 ***/

#pragma config USERID =     0xffff
#pragma config FSRSSEL =    PRIORITY_7
#pragma config FCANIO =     ON
#pragma config FUSBIDIO =   OFF
#pragma config FVBUSONIO =  OFF


// *****************************************************************************
// *****************************************************************************
// Section: Library/Stack Initialization Data
// *****************************************************************************
// *****************************************************************************/



// *****************************************************************************
// *****************************************************************************
// Section: Driver Initialization Data
// *****************************************************************************
// *****************************************************************************

//<editor-fold defaultstate="collapsed" desc="DRV_USART Configuration">

// </editor-fold>
//<editor-fold defaultstate="collapsed" desc="DRV_I2C Configuration">
// </editor-fold>

// *****************************************************************************
// *****************************************************************************
// Section: System Data
// *****************************************************************************
// *****************************************************************************

/* Structure to hold the object handles for the modules in the system. */
SYSTEM_OBJECTS sysObj;

// *****************************************************************************
// *****************************************************************************
// Section: Module Initialization Data
// *****************************************************************************
// *****************************************************************************


//<editor-fold defaultstate="collapsed" desc="SYS_DEVCON Configuration">

/*** System Device Control Initialization Data ***/

const SYS_DEVCON_INIT sysDevconInit =
{
    .moduleInit = {0},
};
// </editor-fold>

// *****************************************************************************
// *****************************************************************************
// Section: Static Initialization Functions
// *****************************************************************************
// *****************************************************************************


/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  cfg_tbl_check
 *  Description:  检测存储芯片内的配置参数是否正常。
 * =====================================================================================
 */
uint8_t cfg_tbl_check(void){

	uint8_t i;
	uint8_t ret;
	uint8_t temp[16] = {0};

//	for ( i = 0; i < 3; i += 1 ) { /*如果读取IIC返回错误，则重复读取三遍。*/ 
//		ret = read_conitue(0xAE, 0x00, 0x00, temp, 16);
//		if(ret == true){
//			break;
//		}
//	}
//	if(i >= 3){		
//		PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//		printf("Load Config Table Error[-1], Load default param now!\r\n");
//		PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//                return false;
//	}
//
//	if((temp[0] != 0x7777) || (temp[8] != 0x7777) || (temp[15] != 0x7777)){
//		PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//		printf("Load Config Table Error[-2], Load default param now!\r\n");
//		PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//                return false;
//	}
//        delay_time(10000);
	for ( i = 0; i < 3; i += 1 ) { /*如果读取IIC返回错误，则重复读取三遍。*/ 
		ret = read_conitue(0xAE, 0x01, 0x00, temp, 16);
		if(ret == true){
			break;
		}
	}
	if(i >= 3){
		PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
		printf("Load Config Table Error[-1], Load default param now!\r\n");
		PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
                return false;
	}

	if((temp[0] != 0x77) || (temp[8] != 0x77) || (temp[15] != 0x77)){
		PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
		printf("Load Config Table Error[-2], Load default param now!\r\n");
		PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
                return false;
	}

	return true;
}		/* -----  end of function cfg_tbl_check  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  load_default_cfg_tbl
 *  Description:  导入默认的配置信息表
 * =====================================================================================
 */
void load_default_cfg_tbl(void){

	uint16_t i;

	for ( i = 0; i < CFG_TBL_SIZE; i += 1 ) {
		cfg_tbl_temp[i] = 0x00; 
	}

        cfg_tbl_temp[CFG_OFS_CAN_DEBUG_LEVEL] = 0x00;  //调试等级
	cfg_tbl_temp[CFG_OFS_DEV_ADDR] = 0x02;         //默认设备地址为2
	cfg_tbl_temp[CFG_OFS_CAN_BAUD_RATE] = 0x00;    //默认波特率为125KPBS
        cfg_tbl_temp[CFG_OFS_FRE_RATE] = 2700;         //默认输出频率为27Hz
        cfg_tbl_temp[CFG_OFS_AO_CHANNEL] = 0;          //默认为主路输出。
        cfg_tbl_temp[CFG_OFS_AO_SHOW_DOWN] = 1;        //默认100ms间隔降低AO输出
        cfg_tbl_temp[CFG_OFS_AO_SPEED_UP] = 1;         //默认100ms间隔升高AO输出

        cfg_tbl_temp[CFG_OFS_AI1_LO_VALUE] = 0;        //AI1下限制默认为0
        cfg_tbl_temp[CFG_OFS_AI1_HI_VALUE] = 5000;      //AI1上限值默认为5000
        cfg_tbl_temp[CFG_OFS_AI2_LO_VALUE] = 0;        //AI2下限制默认为0
        cfg_tbl_temp[CFG_OFS_AI2_HI_VALUE] = 5000;      //AI2上限值默认为5000

        cfg_tbl_temp[CFG_OFS_DO1_KEEP] = 2000;      //DO1脉冲保持时间
        cfg_tbl_temp[CFG_OFS_DO2_KEEP] = 2000;      //DO2脉冲保持时间
	return ;
}		/* -----  end of function load_default_cfg_tbl  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  load_cal_para
 *  Description:  读取校准参数。
 * =====================================================================================
 */
void load_cal_para(void){

	uint8_t ret;
        uint8_t j;
	uint16_t addr = 0x0100 - 32;    //地址0x0100用于判断eeprom数据是否正常。 -32用于存储校准信息。
	uint8_t temp[32] = {0};

	delay_time(10000);
	ret = read_conitue(0xAE, ((addr >> 8) & 0x00ff), ((addr >> 0) & 0x00ff), &temp[0], 16);
	addr = 0x0100 - 16;    		//地址0x0100用于判断eeprom数据是否正常。 -16用于存储校准信息。
	delay_time(10000);
	ret = read_conitue(0xAE, ((addr >> 8) & 0x00ff), ((addr >> 0) & 0x00ff), &temp[16], 16);
	if(ret == true){
		if((temp[30] == 0x00) && (temp[31] == 0x00)){
			PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
			printf("None Calibration Param, Load default!\r\n");
			PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
			cal_para[CAL_OFS_AOH_LO] = 50;
			cal_para[CAL_OFS_AOH_HI] = 3300;
                        cal_para[CAL_OFS_AOB_LO] = 255;
                        cal_para[CAL_OFS_AOB_HI] = 153;

                        cal_para[CAL_OFS_AI1_LO] = 163;
                        cal_para[CAL_OFS_AI1_HI] = 816;

                        cal_para[CAL_OFS_VOH_LO] = 50;
                        cal_para[CAL_OFS_VOH_HI] = 3300;
			cal_para[CAL_OFS_VOB_LO] = 255;
                        cal_para[CAL_OFS_VOB_HI] = 153;
//                        cal_para[CAL_OFS_AI2_LO] = 163;
//                        cal_para[CAL_OFS_AI2_HI] = 807;
		}else{
			for ( j = 0; j < 16; j += 1 ) {
				cal_para[j] = temp[j*2];
				cal_para[j] = (cal_para[j] << 8) & 0xff00;
				cal_para[j] += temp[j*2 + 1];
			}
                        if((cal_para[0] == 0) && (cal_para[1] == 0)){
                            			PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
			printf("Error Calibration Param, Load default!\r\n");
			PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
			cal_para[CAL_OFS_AOH_LO] = 50;
			cal_para[CAL_OFS_AOH_HI] = 3300;
                        cal_para[CAL_OFS_AOB_LO] = 255;
                        cal_para[CAL_OFS_AOB_HI] = 153;

                        cal_para[CAL_OFS_AI1_LO] = 163;
                        cal_para[CAL_OFS_AI1_HI] = 816;

                        cal_para[CAL_OFS_VOH_LO] = 50;
                        cal_para[CAL_OFS_VOH_HI] = 3300;
			cal_para[CAL_OFS_VOB_LO] = 255;
                        cal_para[CAL_OFS_VOB_HI] = 153;
                        }
			PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
			printf("Load Calibration Param Finished!\r\n");
			PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);	
		}
	}

	return ;
}		/* -----  end of function load_cal_para  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  load_cfg_tbl
 *  Description:  从外部存储芯片导入配置参数。
 * =====================================================================================
 */
void load_cfg_tbl(void){

	uint16_t i;
	uint16_t j;
	uint8_t ret;
	uint8_t para_temp[16];

	ret = cfg_tbl_check();
	if(ret == true){
		for ( i = 0; i < 8; i += 1 ) {
			ret = read_conitue(0xAE, 0x00, (0x00 + i*16), para_temp, 16);
			if(ret == true){
				for ( j = 0; j < 8; j += 1 ) {
					cfg_tbl_temp[j + i*8] = para_temp[j*2];
					cfg_tbl_temp[j + i*8] = (cfg_tbl_temp[j + i*8] << 8) & 0xff00;
					cfg_tbl_temp[j + i*8] += para_temp[j*2 + 1];
				}
				delay_time(10000);
			}
		}
                PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
		printf("Load Config Table Finished!\r\n");
		PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	}else{
		load_default_cfg_tbl();
	}

	load_cal_para();
	for ( i = 0; i < CFG_TBL_SIZE; i += 1 ) {
		cfg_tbl[i] = cfg_tbl_temp[i];
	}
        cfg_tbl[CFG_OFS_SOFT_V] = SOFT_VERSION;     //当前软件版本号
	return ;
}		/* -----  end of function load_cfg_tbl  ----- */

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  DRV_AI_Init
 *  Description:  初始化模拟量采集配置。
 * =====================================================================================
 */
void DRV_AI_Init(void){

        AD1CON1bits.SSRC = 0X07; //由内部计数器结束采样并启动转换 （自动转换）

        AD1CON2bits.VCFG = 0x03; //参考电压选择，外部 VREF+ 引脚 外部 VREF- 引脚
	AD1CON2bits.SMPI = 0X01; //完成1次采样后产生中断。
	AD1CON2bits.BUFM = 0x01; //缓冲区配置为两个 8 字缓冲区 ADC1BUF(7...0) 和 ADC1BUF(15...8)
        AD1CON2bits.ALTS = 0x01; //MUX A和MUX B 交替采样。
        AD1CON2bits.CSCNA = 0x00;//无输入扫描

        AD1CHSbits.CH0SA = 0x05; //AN5作为MUX A同相输入
        AD1CHSbits.CH0NA = 0x00; //通道 0 的反相输入为 VR
        AD1CHSbits.CH0SB = 0x04; //AN4作为MUX B同相输入
        AD1CHSbits.CH0NB = 0x00; //通道 1 的反相输入为 VR

//        AD1CSSL = 0x0000;        //0 = 输入扫描时跳过 ANx
//
//        IFS1CLR = 0x0002; // Ensure the interrupt flag is clear
//        IEC1SET = 0x0002; // Enable ADC interrupts
        AD1CON1SET = 0x8000; // turn ADC ON

	return ;
}		/* -----  end of function DRV_AI_Init  ----- */


// *****************************************************************************
// *****************************************************************************
// Section: System Initialization
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void SYS_Initialize ( SYS_INIT_DATA *data )

  Summary:
    Initializes the board, services, drivers, application and other modules.

  Remarks:
    See prototype in system/common/sys_module.h.
 */

void SYS_Initialize ( void* data )
{
    OS_ERR os_err;

    /*initialize RTOS */
    CPU_Init();
    OSInit(&os_err);
    /* Core Processor Initialization */
    SYS_CLK_Initialize( NULL );
    sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit);
    SYS_DEVCON_PerformanceConfig(SYS_CLK_SystemFrequencyGet());
    SYS_DEVCON_JTAGDisable();
    SYS_PORTS_Initialize();

    DRV_USART0_Initialize();
    /* Initialize Drivers */
    /* Initialize ADC */
    DRV_AI_Init();
//    DRV_ADC_Initialize();

    DRV_I2C0_Initialize();
    load_cfg_tbl();
    DRV_I2C1_Initialize();

    /*Initialize CAN0 */
    DRV_CAN0_Initialize();

    /* Initialize System Services */
    SYS_INT_Initialize();

    /* Initialize Middleware */

    
    //以下代码是控制系统时钟，原在 APP_Initialize();中部分
    /*setup rtos tick interrupt source, for 1ms tick*/
    __builtin_mtc0(11, 0, 100000);
    /*start counting from zero*/
    __builtin_mtc0(9, 0, 0);
    /*clear interrupt flag, before enabling*/
    PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_TIMER_CORE);
    /*enable interrupt source and set IPL for core timer*/
    PLIB_INT_VectorPrioritySet(INT_ID_0, INT_VECTOR_CT, INT_PRIORITY_LEVEL2);
    PLIB_INT_SourceEnable(INT_ID_0, INT_SOURCE_TIMER_CORE);

    /* Initialize the Application */
    APP_Initialize();
    APP1_Initialize();
    APP2_Initialize();
    APP3_Initialize();
    APP4_Initialize();
    APP5_Initialize();

}

/*******************************************************************************
 End of File
*/

